﻿using System;
using System.Collections.Generic;
using System.Linq;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Structure;
using Autodesk.Revit.UI.Selection;
using YJKRGeometry;
using QuickModel.InteractiveOperation;
using Transfer.Utils;

namespace QuickModel.CommonTrans
{
	public class RevitCommonFunctions
	{
		public static List<Family> GetFamilysFromDoc(Autodesk.Revit.DB.Document doc)
		{
			List<Family> list = new List<Family>();
			List<string> list2 = new List<string>();
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(doc);
			List<Element> list3 = filteredElementCollector.OfClass(typeof(Family)).WhereElementIsNotElementType().ToElements().ToList<Element>();
			bool flag = list3 != null && list3.Count > 0;
			if (flag)
			{
				foreach (Element element in list3)
				{
					Family family = element as Family;
					bool flag2 = family == null || !family.IsValidObject || string.IsNullOrEmpty(family.Name);
					if (!flag2)
					{
						bool flag3 = !list2.Contains(family.Name);
						if (!flag3)
						{
							list.Add(family);
							list2.Add(family.Name);
						}
					}
				}
			}
			return list;
		}

		public static Family GetFamilyFromDoc(Autodesk.Revit.DB.Document doc, string familyName)
		{
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(doc);
			List<Element> list = filteredElementCollector.OfClass(typeof(Family)).WhereElementIsNotElementType().ToElements().ToList<Element>();
			bool flag = list != null && list.Count > 0;
			if (flag)
			{
				foreach (Element element in list)
				{
					Family family = element as Family;
					bool flag2 = family == null || !family.IsValidObject || string.IsNullOrEmpty(family.Name);
					if (!flag2)
					{
						bool flag3 = family.Name == familyName;
						if (flag3)
						{
							return family;
						}
					}
				}
			}
			return null;
		}

		public static List<Family> GetCurDocFamilys(Autodesk.Revit.DB.Document doc, List<BuiltInCategory> categorys, List<string> containInfos)
		{
			bool flag = categorys == null || categorys.Count <= 0;
			List<Family> result;
			if (flag)
			{
				result = new List<Family>();
			}
			else
			{
				List<Family> list = new List<Family>();
				foreach (BuiltInCategory category in categorys)
				{
					list.AddRange(RevitCommonFunctions.GetCurDocFamilys(doc, category, containInfos));
				}
				result = list;
			}
			return result;
		}

		public static List<Family> GetCurDocFamilys(Autodesk.Revit.DB.Document doc, List<BuiltInCategory> categorys, List<string> containInfos, List<string> noContainInfos)
		{
			bool flag = categorys == null || categorys.Count <= 0;
			List<Family> result;
			if (flag)
			{
				result = new List<Family>();
			}
			else
			{
				List<Family> list = new List<Family>();
				foreach (BuiltInCategory category in categorys)
				{
					list.AddRange(RevitCommonFunctions.GetCurDocFamilys(doc, category, containInfos, noContainInfos));
				}
				result = list;
			}
			return result;
		}

		public static List<Family> GetCurDocFamilys(Autodesk.Revit.DB.Document doc, BuiltInCategory category, List<string> containInfos)
		{
			List<Family> list = new List<Family>();
			List<string> list2 = new List<string>();
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(doc);
			List<Element> list3 = filteredElementCollector.OfClass(typeof(Family)).WhereElementIsNotElementType().ToElements().ToList<Element>();
			bool flag = list3 != null && list3.Count > 0;
			if (flag)
			{
				foreach (Element element in list3)
				{
					Family family = element as Family;
					bool flag2 = family == null || !family.IsValidObject || string.IsNullOrEmpty(family.Name) || list2.Contains(family.Name);
					if (!flag2)
					{
						bool flag3 = family.FamilyCategory == null || family.FamilyCategory.Id.IntegerValue != category;
						if (!flag3)
						{
							bool flag4 = containInfos != null && containInfos.Count > 0 && !RevitCommonFunctions.CheckListHaveValue(containInfos, family.Name);
							if (!flag4)
							{
								list.Add(family);
								list2.Add(family.Name);
							}
						}
					}
				}
			}
			return list;
		}

		public static List<Family> GetCurDocFamilys(Autodesk.Revit.DB.Document doc, BuiltInCategory category, List<string> containInfos, List<string> noContainInfos)
		{
			List<Family> list = new List<Family>();
			List<string> list2 = new List<string>();
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(doc);
			List<Element> list3 = filteredElementCollector.OfClass(typeof(Family)).WhereElementIsNotElementType().ToElements().ToList<Element>();
			bool flag = list3 != null && list3.Count > 0;
			if (flag)
			{
				foreach (Element element in list3)
				{
					Family family = element as Family;
					bool flag2 = family == null || !family.IsValidObject || string.IsNullOrEmpty(family.Name) || list2.Contains(family.Name);
					if (!flag2)
					{
						bool flag3 = family.FamilyCategory == null || family.FamilyCategory.Id.IntegerValue != category;
						if (!flag3)
						{
							bool flag4 = containInfos != null && containInfos.Count > 0 && !RevitCommonFunctions.CheckListHaveValue(containInfos, family.Name);
							if (!flag4)
							{
								bool flag5 = noContainInfos != null && noContainInfos.Count > 0 && RevitCommonFunctions.CheckListHaveValue(noContainInfos, family.Name);
								if (!flag5)
								{
									list.Add(family);
									list2.Add(family.Name);
								}
							}
						}
					}
				}
			}
			return list;
		}

		public static bool CheckListHaveValue(List<string> lst, string value)
		{
			bool flag = lst == null || lst.Count <= 0 || string.IsNullOrEmpty(value);
			bool result;
			if (flag)
			{
				result = false;
			}
			else
			{
				foreach (string value2 in lst)
				{
					bool flag2 = value.Contains(value2);
					if (flag2)
					{
						return true;
					}
				}
				result = false;
			}
			return result;
		}

		public static List<FamilySymbol> GetFamilySymbols(Family f)
		{
			bool flag = f == null;
			List<FamilySymbol> result;
			if (flag)
			{
				result = new List<FamilySymbol>();
			}
			else
			{
				List<FamilySymbol> list = new List<FamilySymbol>();
				ISet<ElementId> familySymbolIds = f.GetFamilySymbolIds();
				foreach (ElementId elementId in familySymbolIds)
				{
					FamilySymbol familySymbol = f.Document.GetElement(elementId) as FamilySymbol;
					bool flag2 = familySymbol != null;
					if (flag2)
					{
						list.Add(familySymbol);
					}
				}
				result = list;
			}
			return result;
		}

		public static List<string> GetFamilySymbolNames(Family f)
		{
			bool flag = f == null;
			List<string> result;
			if (flag)
			{
				result = new List<string>();
			}
			else
			{
				List<string> list = new List<string>();
				ISet<ElementId> familySymbolIds = f.GetFamilySymbolIds();
				foreach (ElementId elementId in familySymbolIds)
				{
					FamilySymbol familySymbol = f.Document.GetElement(elementId) as FamilySymbol;
					bool flag2 = familySymbol != null && !string.IsNullOrEmpty(familySymbol.Name) && !string.IsNullOrEmpty(familySymbol.Name.Trim()) && !list.Contains(familySymbol.Name.Trim());
					if (flag2)
					{
						list.Add(familySymbol.Name.Trim());
					}
				}
				list.Sort();
				result = list;
			}
			return result;
		}

		public static FamilySymbol GetFamilySymbol(Family f, string familySymbolName)
		{
			bool flag = f == null;
			FamilySymbol result;
			if (flag)
			{
				result = null;
			}
			else
			{
				List<FamilySymbol> list = new List<FamilySymbol>();
				ISet<ElementId> familySymbolIds = f.GetFamilySymbolIds();
				foreach (ElementId elementId in familySymbolIds)
				{
					FamilySymbol familySymbol = f.Document.GetElement(elementId) as FamilySymbol;
					bool flag2 = familySymbol != null && familySymbolName == familySymbol.Name;
					if (flag2)
					{
						return familySymbol;
					}
				}
				result = null;
			}
			return result;
		}

		public static FamilySymbol GetFirstFamilySymbol(Family f)
		{
			bool flag = f == null;
			FamilySymbol result;
			if (flag)
			{
				result = null;
			}
			else
			{
				List<FamilySymbol> list = new List<FamilySymbol>();
				ISet<ElementId> familySymbolIds = f.GetFamilySymbolIds();
				foreach (ElementId elementId in familySymbolIds)
				{
					FamilySymbol familySymbol = f.Document.GetElement(elementId) as FamilySymbol;
					bool flag2 = familySymbol != null;
					if (flag2)
					{
						return familySymbol;
					}
				}
				result = null;
			}
			return result;
		}

		public static XYZ GetElementLocation(Element e)
		{
			LocationPoint locationPoint = e.Location as LocationPoint;
			bool flag = locationPoint == null;
			XYZ result;
			if (flag)
			{
				LocationCurve locationCurve = e.Location as LocationCurve;
				bool flag2 = locationCurve != null && locationCurve.Curve != null;
				if (flag2)
				{
					Curve curve = locationCurve.Curve;
					result = (curve.GetEndPoint(0) + curve.GetEndPoint(1)) / 2.0;
				}
				else
				{
					result = null;
				}
			}
			else
			{
				result = locationPoint.Point;
			}
			return result;
		}

		public static bool GetRotationAngle(Element e, out double angle)
		{
			angle = 0.0;
			LocationPoint locationPoint = e.Location as LocationPoint;
			bool flag = locationPoint == null;
			bool result;
			if (flag)
			{
				result = false;
			}
			else
			{
				angle = locationPoint.Rotation;
				result = true;
			}
			return result;
		}

		public static XYZ GetElementBoxCenter(Autodesk.Revit.DB.Document doc, Element e)
		{
			bool flag = e != null;
			if (flag)
			{
				BoundingBoxXYZ boundingBoxXYZ = e.get_BoundingBox(doc.ActiveView);
				bool flag2 = boundingBoxXYZ != null;
				if (flag2)
				{
					return (boundingBoxXYZ.Min + boundingBoxXYZ.Max) / 2.0;
				}
			}
			return null;
		}

		public static bool DeleteElementsForDoc(Autodesk.Revit.DB.Document doc, List<ElementId> ids, out string exMessage)
		{
			exMessage = string.Empty;
			bool flag = ids == null || ids.Count <= 0;
			bool result;
			if (flag)
			{
				result = true;
			}
			else
			{
				Transaction transaction = new Transaction(doc, "Del");
				try
				{
					transaction.Start();
					doc.Delete(ids);
					result = true;
				}
				catch
				{
					exMessage = "删除元素失败!";
					result = false;
				}
				finally
				{
					bool flag2 = (int)transaction.GetStatus() == 1;
					if (flag2)
					{
						transaction.Commit();
					}
				}
			}
			return result;
		}

		public static List<Element> GetInstancesByOutLine(Autodesk.Revit.DB.Document doc, XYZ location, double distance)
		{
			List<Element> list = new List<Element>();
			XYZ xyz = new XYZ(distance, distance, distance);
			Outline outline = new Outline(location - xyz, location + xyz);
			BoundingBoxIntersectsFilter boundingBoxIntersectsFilter = new BoundingBoxIntersectsFilter(outline);
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(doc);
			FilteredElementCollector filteredElementCollector2 = filteredElementCollector.OfClass(typeof(FamilyInstance)).OfCategory(BuiltInCategory.OST_GenericModel);
			IList<Element> list2 = filteredElementCollector2.WherePasses(boundingBoxIntersectsFilter).ToElements();
			foreach (Element element in list2)
			{
				FamilyInstance familyInstance = element as FamilyInstance;
				bool flag = familyInstance == null || familyInstance.Symbol == null || familyInstance.Symbol.Family == null || string.IsNullOrEmpty(familyInstance.Symbol.Family.Name);
				if (!flag)
				{
					list.Add(element);
				}
			}
			return list;
		}

		public static FamilyInstance NewFamilyInstance(Autodesk.Revit.DB.Document doc, FamilySymbol familySymbol, XYZ location, StructuralType structuralType)
		{
			bool flag = familySymbol != null;
			FamilyInstance result;
			if (flag)
			{
				bool flag2 = !familySymbol.IsActive;
				if (flag2)
				{
					familySymbol.Activate();
				}
				FamilyInstance familyInstance = doc.Create.NewFamilyInstance(location, familySymbol, structuralType);
				result = familyInstance;
			}
			else
			{
				result = null;
			}
			return result;
		}

		public static FamilyInstance NewFamilyInstance(Autodesk.Revit.DB.Document doc, FamilySymbol familySymbol, XYZ location, Level level, StructuralType structuralType)
		{
			bool flag = familySymbol != null;
			FamilyInstance result;
			if (flag)
			{
				bool flag2 = !familySymbol.IsActive;
				if (flag2)
				{
					familySymbol.Activate();
				}
				FamilyInstance familyInstance = doc.Create.NewFamilyInstance(location, familySymbol, level, structuralType);
				result = familyInstance;
			}
			else
			{
				result = null;
			}
			return result;
		}

		public static int GetFamilyHostType(Family f)
		{
			bool flag = f == null;
			int result;
			if (flag)
			{
				result = -1;
			}
			else
			{
				Parameter parameter = f.get_Parameter(BuiltInParameter.FAMILY_HOSTING_BEHAVIOR);
				bool flag2 = parameter == null;
				if (flag2)
				{
					result = -1;
				}
				else
				{
					result = parameter.AsInteger();
				}
			}
			return result;
		}

		public static List<Family> GetBasePointPlaceFamilys(List<Family> familys)
		{
			bool flag = familys == null || familys.Count <= 0;
			List<Family> result;
			if (flag)
			{
				result = new List<Family>();
			}
			else
			{
				List<Family> list = new List<Family>();
				foreach (Family family in familys)
				{
					bool flag2 = !RevitCommonFunctions.CheckFamilyIsBasePointPlace(family);
					if (!flag2)
					{
						bool flag3 = list.Contains(family);
						if (!flag3)
						{
							list.Add(family);
						}
					}
				}
				result = list;
			}
			return result;
		}

		public static bool CheckFamilyIsBasePointPlace(Family f)
		{
			int familyHostType = RevitCommonFunctions.GetFamilyHostType(f);
			bool flag = familyHostType == 0;
			if (flag)
			{
				bool flag2 = f.FamilyPlacementType != 5 && f.FamilyPlacementType != 6 && f.FamilyPlacementType != 7;
				if (flag2)
				{
					return true;
				}
			}
			return false;
		}

		public static bool CheckPointIsInBox(PickedBox pickBox, XYZ ptPos)
		{
			bool flag = pickBox == null || ptPos == null;
			bool result;
			if (flag)
			{
				result = false;
			}
			else
			{
				XYZ xyz = new XYZ(Math.Min(pickBox.Min.X, pickBox.Max.X), Math.Min(pickBox.Min.Y, pickBox.Max.Y), 0.0);
				XYZ xyz2 = new XYZ(Math.Max(pickBox.Min.X, pickBox.Max.X), Math.Max(pickBox.Min.Y, pickBox.Max.Y), 0.0);
				bool flag2 = ptPos.X > xyz.X && ptPos.Y > xyz.Y && ptPos.X < xyz2.X && ptPos.Y < xyz2.Y;
				result = flag2;
			}
			return result;
		}

		public static List<XYZ> GetCurveEndPoints(Curve c)
		{
			bool flag = c == null;
			List<XYZ> result;
			if (flag)
			{
				result = new List<XYZ>();
			}
			else
			{
				List<XYZ> list = new List<XYZ>();
				bool flag2 = c is Line;
				if (flag2)
				{
					list.Add(c.GetEndPoint(0));
					list.Add(c.GetEndPoint(1));
				}
				else
				{
					bool flag3 = c is Arc;
					if (flag3)
					{
						Arc arc = c as Arc;
						bool isBound = arc.IsBound;
						if (isBound)
						{
							list.Add(arc.GetEndPoint(0));
							list.Add(arc.GetEndPoint(1));
						}
						else
						{
							XYZ item = arc.Center - arc.Radius * XYZ.BasisX;
							XYZ item2 = arc.Center + arc.Radius * XYZ.BasisX;
							list.Add(item);
							list.Add(item2);
						}
					}
					else
					{
						bool flag4 = c is Ellipse;
						if (flag4)
						{
							Ellipse ellipse = c as Ellipse;
							bool isBound2 = ellipse.IsBound;
							if (isBound2)
							{
								list.Add(ellipse.GetEndPoint(0));
								list.Add(ellipse.GetEndPoint(1));
							}
							else
							{
								XYZ item3 = ellipse.Center - ellipse.RadiusX * XYZ.BasisX;
								XYZ item4 = ellipse.Center + ellipse.RadiusX * XYZ.BasisX;
								list.Add(item3);
								list.Add(item4);
							}
						}
					}
				}
				result = list;
			}
			return result;
		}

		public static double GetRightAngle(double angle)
		{
			ToleranceManger toleranceManger = ToleranceManger.GetToleranceManger();
			double tolerance = toleranceManger.GetTolerance("末端快模-角度公差");
			bool flag = Transfer.Utils.Geometry.IsEqual(angle, 0.0, tolerance);
			double result;
			if (flag)
			{
				result = angle;
			}
			else
			{
				bool flag2 = angle <= 0.0;
				double num;
				for (num = Math.Abs(angle); num > Math.PI*2; num -= Math.PI*2)
				{
				}
				result = (flag2 ? (-num) : num);
			}
			return result;
		}

		public static bool GetCadElementLayer(ICadElement cadElem, ref string strUseLayer, ref Category layerCategory)
		{
			bool flag = cadElem == null;
			bool result;
			if (flag)
			{
				result = false;
			}
			else
			{
				bool flag2 = cadElem is CurveInfo;
				if (flag2)
				{
					CurveInfo curveInfo = cadElem as CurveInfo;
					bool flag3 = string.IsNullOrWhiteSpace(curveInfo.UseLayerName) || curveInfo.RevitLayer == null;
					if (flag3)
					{
						return false;
					}
					strUseLayer = curveInfo.UseLayerName;
					layerCategory = curveInfo.RevitLayer;
				}
				else
				{
					bool flag4 = cadElem is TextInfo;
					if (flag4)
					{
						TextInfo textInfo = cadElem as TextInfo;
						bool flag5 = string.IsNullOrWhiteSpace(textInfo.UseLayerName) || textInfo.RevitLayer == null;
						if (flag5)
						{
							return false;
						}
						strUseLayer = textInfo.UseLayerName;
						layerCategory = textInfo.RevitLayer;
					}
					else
					{
						bool flag6 = cadElem is BlockInfo;
						if (!flag6)
						{
							return false;
						}
						BlockInfo blockInfo = cadElem as BlockInfo;
						bool flag7 = string.IsNullOrWhiteSpace(blockInfo.UseLayerName) || blockInfo.RevitLayer == null;
						if (flag7)
						{
							return false;
						}
						strUseLayer = blockInfo.UseLayerName;
						layerCategory = blockInfo.RevitLayer;
					}
				}
				result = true;
			}
			return result;
		}

		public static bool IsElementInBox(ICadElement element, PickedBox pickBox)
		{
			foreach (Curve curve in element.BoundingBoxCurve)
			{
				XYZ ptTest = null;
				XYZ ptTest2 = null;
				bool isBound = curve.IsBound;
				if (isBound)
				{
					ptTest = curve.GetEndPoint(0);
					ptTest2 = curve.GetEndPoint(1);
				}
				else
				{
					bool flag = curve is Arc;
					if (flag)
					{
						Arc arc = curve as Arc;
						ptTest = arc.Center;
						ptTest2 = arc.Center;
					}
				}
				bool flag2 = !RevitCommonFunctions.IsPointInPickBox(ptTest, pickBox);
				if (flag2)
				{
					return false;
				}
				bool flag3 = !RevitCommonFunctions.IsPointInPickBox(ptTest2, pickBox);
				if (flag3)
				{
					return false;
				}
			}
			return true;
		}

		private static bool IsPointInPickBox(XYZ ptTest, PickedBox pickBox)
		{
			double val = Math.Min(pickBox.Min.X, pickBox.Max.X);
			double val2 = Math.Max(pickBox.Min.X, pickBox.Max.X);
			double val3 = Math.Min(pickBox.Min.Y, pickBox.Max.Y);
			double val4 = Math.Max(pickBox.Min.Y, pickBox.Max.Y);
			bool flag = YJKRGeometry.Geometry.LessThan(ptTest.X, val) || YJKRGeometry.Geometry.GreaterThan(ptTest.X, val2);
			bool result;
			if (flag)
			{
				result = false;
			}
			else
			{
				bool flag2 = YJKRGeometry.Geometry.LessThan(ptTest.Y, val3) || YJKRGeometry.Geometry.GreaterThan(ptTest.Y, val4);
				result = !flag2;
			}
			return result;
		}
	}
}
